<!--
 * @Author: C.
 * @Date: 2024-07-30 20:41:51
-->
<template>
  <div class="drag-container">
    <slot></slot>
    <div
      class="mark-line"
      v-for="(item, index) in markLine"
      :key="index"
      :style="item"
    ></div>
  </div>
</template>
<script lang="ts" setup>
// ----------------------------- 第三方引入 -----------------------------
import { compile, computed, provide, reactive, ref } from "vue";
import { IPositon } from "./types";
import type { ComputedRef, CSSProperties } from "vue";
// ----------------------------- hooks -----------------------------

// ----------------------------- 组件 -----------------------------

// ----------------------------- 其他引入 -----------------------------
const markLine = reactive<Record<string, CSSProperties>>({
  xline: {
    width: "100%",
    height: "1px",
    left: 0,
    top: 0
  },
  yline: {
    height: "100%",
    width: "1px",
    left: 0,
    top: 0
  }
});
const curentId = ref<string>();
//----------------------------- 变量声明区 -----------------------------
const boxStore = reactive<Record<string, IPositon>>({});
// ----------------------------- hooks使用区 -----------------------------
function updateBoxStore(id: string, pos: IPositon) {
  curentId.value = id;
  boxStore[id] = pos;
  showMarkLine(id, pos);
}

function showMarkLine(id: string, pos: IPositon) {
  let lineX = 999;
  let lineY = 999;
  let positiony = 999;
  let positionx = 999;
  lines.value.y.forEach((item) => {
    let minX = Math.min(
      Math.abs(item - pos.y),
      Math.abs(item - pos.y - pos.h / 2),
      Math.abs(item - pos.y - pos.h)
    );
    if (lineX > minX) {
      lineX = minX;
      positiony = item;
    }
  });

  lines.value.x.forEach((item) => {
    let maxY = Math.min(
      Math.abs(item - pos.x),
      Math.abs(item - pos.x - pos.w / 2),
      Math.abs(item - pos.x - pos.w)
    );
    if (lineY > maxY) {
      lineY = maxY;
      positionx = item;
    }
  });

  if (lineX < 20) {
    markLine["xline"].display = "block";
    markLine["xline"].top = positiony + "px";
  } else {
    markLine["xline"].display = "none";
  }
  if (lineY < 20) {
    markLine["yline"].display = "block";
    markLine["yline"].left = positionx + "px";
  } else {
    markLine["yline"].display = "none";
  }
}
const lines = computed(() => {
  const y = [],
    x = [];
  for (const key in boxStore) {
    if (curentId.value !== key) {
      const target = boxStore[key];
      y.push(target.y);
      y.push(target.y + target.h / 2);
      y.push(target.y + target.h);

      x.push(target.x);
      x.push(target.x + target.w / 2);
      x.push(target.x + target.w);
    }
  }
  return {
    y,
    x
  };
});
function hideMarkLine() {
  markLine["xline"].display = "none";
  markLine["yline"].display = "none";
}
provide("updateBoxStore", updateBoxStore);
provide("hideMarkLine", hideMarkLine);
// ----------------------------- 钩子函数区 -----------------------------

//  ----------------------------- 自定义方法区 -----------------------------
</script>
<style lang="scss" scoped>
.drag-container {
  position: relative;
  width: 1000px;
  height: 700px;
  background-color: #00000049;
  .mark-line {
    position: absolute;
    background-color: rgb(255, 255, 255);
    display: none;
  }
}
</style>
